﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Logistics.DataManage.Local;
using Logistics.DataManage.Server;
using Logistics.Utils;
using MapgisEbp.QuickDataBase;
using MapgisEbp.QuickDataBase.Common;

namespace Logistics.DataManage
{
    [Obsolete("该类已过时，请使用CustomerDownloader类")]
    class CustomerDataDownloader
    {
        /// <summary>
        /// 分批次下载并更新本地客户数据
        /// </summary>
        public static void DownloadCustomers()
        {
            int stagesDays = 10;//一次更新10天的数据，避免一次获取海量数据
            LogUtils.WriteDebug(String.Format("准备更新customs表,每次更新{0}天数据", stagesDays));

            DateTime Now = DateTime.Now;
            DateTime lastTimeline = GetLastDownloadTime();
            DateTime newTimeline = lastTimeline.AddDays(stagesDays);
            LogUtils.WriteDebug(String.Format("上次更新时间{0}", lastTimeline));

            while ((Now - lastTimeline).Minutes>1)//大于1分钟才更新
            {
                LogUtils.WriteDebug(String.Format("本次更新从{0}到{1}的数据", lastTimeline, newTimeline));
                DownloadCustomers(lastTimeline, newTimeline);
                lastTimeline = newTimeline;
                newTimeline = lastTimeline.AddDays(stagesDays);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public static void DownloadCustomers(DateTime lastTimeline,DateTime newTimeline)
        {
            try
            {
                //获取服务器端数据
                DataSet svrData = GetSvrCustomDate(lastTimeline, newTimeline);
                LogUtils.WriteDebug(String.Format("从服务器获取到{0}条客户数据", svrData == null ? 0 : svrData.Tables[0].Rows.Count));
                //将从服务器获取到的数据写入临时表
                if (svrData != null && svrData.Tables[0].Rows.Count > 0)
                {
                    StoreCustomersTemp(svrData);
                    TranslateCustomerData();
                }
                //更改客户资料同步的时间
                DateTime updateTime = newTimeline < DateTime.Now ? newTimeline : DateTime.Now;
                String updateTimeString = updateTime.ToString("yyyy-MM-dd HH:mm:ss");
                GlobalObjects.GSetting.LastDownloadTime = updateTimeString;
                LogUtils.WriteDebug(String.Format("本次更新完毕，更新到{0}", updateTimeString));
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 获取服务器上的客户资料
        /// 根据配置文件中上次更新的时间取记录
        /// 如果服务器上客户资料的更新时间晚于配置文件中的上次更新时间，则获取
        /// 如果服务器上客户资料的更新时间早于配置文件中的上次更新时间，则不获取
        /// </summary>
        /// <returns></returns>
        public static DataSet GetSvrCustomDate(DateTime dt,DateTime endt)
        {
            string siteID = GetSiteID();
            return RemoteDateServiceFactory.DateService.GetCustomers(siteID, dt, endt);
        }
        /// <summary>
        /// 将服务器数据插入到本地临时表中
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static int StoreCustomersTemp(DataSet ds)
        {
            //清空临时表数据
            LocalDb.ExecuteNonQuery("delete from CustomsTemp");
            DataTable TemplateDt = LocalDb.TableTemplates["CustomsTemp"];
            IList<String> ColumnNames = DataDownloader.MappingLocalColumns(TemplateDt, ds.Tables[0]);
            String fieldNames = "";
            String values = "";
            foreach (String colName in ColumnNames)
            {
                fieldNames += colName + ",";
                values += "?,";
            }
            fieldNames = fieldNames.TrimEnd(',');
            values = values.TrimEnd(',');
            String sql = "INSERT INTO CustomsTemp(" + fieldNames + ")Values(" + values + ")";
            int rtn = 0;
            DataRowCollection DataRows = ds.Tables[0].Rows;
            int RowCount = DataRows.Count;
            int Size = 500; //每500条记录提交一次事物
            for (int seg = 0; (seg * Size) < RowCount; seg++)
            {
                //启用事物，把数据提交到内存，然后一次写入磁盘，提升批量操作性能
                IDataBaseHandler Handler = LocalDb.Handler;
                using (DbTransactionScope scope = new DbTransactionScope(Handler))
                {
                    try
                    {
                        int start = seg * Size;
                        int end = (seg + 1) * Size;
                        for (int i = start; i < end && i < RowCount; i++)
                        {
                            IList<Object> parameters = new List<Object>();
                            foreach(String colName in ColumnNames)
                            {
                                parameters.Add(DataRows[i][colName]);    
                            }
                            ParameterizedSQL PSQL = Handler.DbAdapter.AdaptSQLAnonymousParams(sql, parameters.ToArray());
                            rtn += Handler.ExecuteNonQuery(PSQL.SQL, PSQL.Parameters);
                        }
                        scope.Complete();
                    }
                    catch (Exception ex)
                    {
                        //事物回滚
                        scope.Dispose();
                        throw ex;
                    }
                }
            }
            return rtn;
        }
        /// <summary>
        /// 删除本地客户表中的记录,将临时数据表中的记录插入到客户表
        /// </summary>
        /// <returns></returns>
        public static int TranslateCustomerData()
        {
            IDataBaseHandler Hander = LocalDb.Handler;
            using (DbTransactionScope scope = new DbTransactionScope(Hander))
            {
                try
                {
                    /*删除本地客户表中的记录
                    1、删除CustomID为空的记录
                    2、删除CustomID在临时表中的记录
                    * */
                    StringBuilder strSQL = new StringBuilder();
                    strSQL.Append("delete from Customs where CustomID in (select CustomID from CustomsTemp) or (IsChecked = 0 or IsChecked is null)");
                    Hander.ExecuteNonQuery(strSQL.ToString());

                    DataTable TemplateDtCus = LocalDb.TableTemplates.Customers;
                    String colNames = "";
                    foreach (DataColumn col in TemplateDtCus.Columns)
                        colNames += col.ColumnName + ",";
                    colNames = colNames.TrimEnd(',');

                    String sql = "INSERT INTO Customs(" + colNames + ") SELECT " + colNames + " from CustomsTemp";
                    int rtn = Hander.ExecuteNonQuery(sql);
                    scope.Complete();
                    return rtn;
                }
                catch
                {
                    scope.Dispose();
                    throw;
                }
            }
        }
        /// <summary>
        /// 从配置文件中读取当前站点编号
        /// </summary>
        /// <returns></returns>
        private static string GetSiteID()
        {
            String siteId = "";
            string siteName = GlobalObjects.GSetting.MachineSiteName;
            if (!String.IsNullOrEmpty(siteName))
            {
                siteId = SitesDAO.GetSiteIdByName(siteName);
            }
            LogUtils.WriteDebug(String.Format("获取本机所在站点,名称={0},ID={1}", siteName, siteId));
            return siteId;
        }

        private static DateTime GetLastDownloadTime()
        {
            DateTime lastTimeline = new DateTime();
            String LastTime = GlobalObjects.GSetting.LastDownloadTime;
            if (!String.IsNullOrEmpty(LastTime))
            {
                DateTime.TryParse(LastTime, out lastTimeline);
            }
            return lastTimeline;
        }
    }
}
